﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using WeChatWASM;
using UnityEditor;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace WXTools
{
    /// <summary>
    /// 微信预加载配置
    /// </summary>
    public class WXPreloadWindow : EditorWindow
    {
        [InitializeOnLoadMethod]
        static void Init()
        {
            Application.logMessageReceived += HandleLog;
            //Debug.Log("<color=blue>绑定完成</color>");
        }
        // 微信转化完成监听器
        private static void HandleLog(string condition, string stackTrace, LogType type)
        {
            string wxFinishExport = "WeChatWASM.WXConvertCore:finishExport";
            if (condition == "[Converter] All done!" && stackTrace.Contains(wxFinishExport))
            {
                WXExportDone();
                //Debug.Log("<color=blue>预加载注入完成</color>");
            }
        }

        static string miniGameDir = Application.dataPath + "/../MiniGame";
        static string filePath = Application.dataPath + "/../ProjectSettings/WXPreload.txt";
        static string abDir = miniGameDir + "/webgl/StreamingAssets/AssetBundle";
        static string jsPath = miniGameDir + "/minigame/game.js";

        [MenuItem("微信小游戏/预加载配置")]

        private static void ShowWindow()
        {
            EditorWindow window = EditorWindow.GetWindow(typeof(WXPreloadWindow));
            window.titleContent = new GUIContent("微信预加载配置");
        }
        static bool isOpen;                            // 窗口是否打开
        static bool configAB;                           // 是否配置AB包（启用将会将其加入预加载列表）
        static List<string> list = new List<string>();   // 配置；列表
        Vector2 scrollView;
        private void OnEnable()
        {
            isOpen = true;
            list.Clear();
            string path = Path.GetFullPath(filePath);
            if (File.Exists(path))
            {
                string json = File.ReadAllText(path, Encoding.UTF8);
                JObject jo = JObject.Parse(json);
                configAB = (bool)jo[nameof(configAB)];
                foreach (var item in jo[nameof(list)])
                {
                    list.Add(item.ToString());
                }
            }
        }
        private void OnDestroy()
        {
            isOpen = false;
            SaveConfig();
        }

        void OnGUI()
        {
            GUILayout.Label("需要在网络空闲时预加载的资源");
            configAB = GUILayout.Toggle(configAB, "将AB包加入预加载列表");
            GUILayout.BeginHorizontal();
            // 添加一行
            if (GUILayout.Button("+", GUILayout.Width(25)))
            {
                list.Add("");
            }
            // 移除最后一行
            if (GUILayout.Button("-", GUILayout.Width(25)) && list.Count > 0)
            {
                list.RemoveAt(list.Count - 1);
            }
            // 清空列表空白行
            if (GUILayout.Button("∅", GUILayout.Width(25)))
            {
                ClearNull();
            }
            // 保存
            if (GUILayout.Button("√", GUILayout.Width(25)))
            {
                ClearNull();
                SaveConfig();
                Debug.Log("<color=yellow>保存成功</color>");
            }
            GUILayout.EndHorizontal();
            scrollView = GUILayout.BeginScrollView(scrollView);
            GUILayout.BeginVertical();
            for (int i = 0; i < list.Count; i++)
            {
                GUILayout.BeginHorizontal();
                GUILayout.Label(i.ToString(), GUILayout.Width(20));
                list[i] = GUILayout.TextField(list[i]);
                GUILayout.EndHorizontal();
            }
            GUILayout.EndVertical();
            GUILayout.EndScrollView();


            GUILayout.BeginHorizontal();

            if (GUILayout.Button("清空目录"))
            {
                if (Directory.Exists(miniGameDir))
                {
                    Directory.Delete(miniGameDir, true);
                }
            }
            if (GUILayout.Button("构建微信小游戏"))
            {
                WXConvertCore.DoExport();
                System.Diagnostics.Process.Start("explorer.exe", Path.GetFullPath(miniGameDir));
            }
            GUILayout.EndHorizontal();
        }
        /// <summary>
        /// 清除空白字符
        /// </summary>
        private void ClearNull()
        {
            for (int i = 0; i < list.Count;)
            {
                if (list[i].Length == 0)
                {
                    list.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }
        }
        // 保存配置
        private void SaveConfig()
        {
            string path = Path.GetFullPath(filePath);
            JObject jo = new JObject();
            JArray ja = new JArray(list);
            jo[nameof(configAB)] = configAB;
            jo[nameof(list)] = ja;
            File.WriteAllText(path, jo.ToString(), Encoding.UTF8);
        }
        /// <summary>
        ///  注入
        /// </summary>
        private static void WXExportDone()
        {
            StringBuilder builder = new StringBuilder();
            string prefix = "		";
            builder.Clear();
            builder.Append("\n" + prefix + "// 开始注入\n");
            if (isOpen)
            {
                foreach (var item in list)
                {
                    builder.Append(prefix + $"'{item}',\n");
                }
            }
            else
            {
                string path = Path.GetFullPath(filePath);
                if (File.Exists(path))
                {
                    string json = File.ReadAllText(path, Encoding.UTF8);
                    JObject jo = JObject.Parse(json);
                    configAB = (bool)jo[nameof(configAB)];
                    foreach (var item in jo[nameof(list)])
                    {
                        builder.Append(prefix + $"'{item}',\n");
                    }
                }
            }

            if (configAB && Directory.Exists(abDir))
            {
                DirectoryInfo info = new DirectoryInfo(abDir);
                var aaFiles = info.GetFiles("*.bundle");
                for (int i = 0; i < aaFiles.Length; i++)
                {
                    string str = aaFiles[i].Name;
                    builder.Append(prefix + $"'/AssetBundle/{str}',\n");
                }
            }
            builder.Append(prefix + "// 结束注入");

            // 注射器
            if (File.Exists(jsPath))
            {
                string pattern = @"(?<=preloadDataList: \[)";
                string js = Regex.Replace(File.ReadAllText(jsPath), pattern, builder.ToString());
                File.WriteAllText(jsPath, js);
            }
        }
    }
}